package com.base.cn.platform.os.service.manage.loreset;

import com.base.cn.platform.os.common.mybatis.BaseBiz;
import com.base.cn.platform.os.common.utils.DataUtil;
import com.base.cn.platform.os.common.utils.ObjectUtils;
import com.base.cn.platform.os.common.utils.StringUtils;
import com.base.cn.platform.os.dao.manage.loreset.SysLoresetPointDao;
import com.base.cn.platform.os.entity.manage.loreset.SysLoreset;
import com.base.cn.platform.os.entity.manage.loreset.SysLoresetPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * 知识体系目录Biz
 *
 * @author s.li
 * @create 2018-03-22 17:27
 */
@Service
public class SysLoresetPointBiz extends BaseBiz<SysLoresetPoint, SysLoresetPointDao> {

    @Autowired
    private SysLoresetBiz sysLoresetBiz;

    /**
     * 删除知识节点
     *
     * @param ids
     */
    public void deleteLoresetPoint(String ids) {
        if (StringUtils.isNotEmpty(ids)) {
            ids = StringUtils.subHeadTailString(ids, ",");
            if (StringUtils.isNotEmpty(ids)) {
                this.deleteWhereSql(" id in (" + ids + ") or parentId in (" + ids + ")");
            }
        }
    }

    /**
     * 修改父级ID
     *
     * @param id       知识点ID
     * @param parentId 知识点新的父级ID
     */
    public void updateLoresetPointParentId(BigDecimal id, BigDecimal parentId) {
        SysLoresetPoint point = new SysLoresetPoint();
        point.setParentId(parentId);
        this.updateByWhereSql(point, " id = " + id);
    }

    /**
     * 保存知识点数据
     *
     * @param loresetPoint 知识点数据对象
     * @return 保存成功的知识点对象
     */
    public SysLoresetPoint saveLoresetPoint(SysLoresetPoint loresetPoint) {
        if (ObjectUtils.isNotEmpty(loresetPoint)) {
            //修改
            if (DataUtil.idIsNotNull(loresetPoint.getId())) {
                SysLoresetPoint _loresetPoint = this.findById(loresetPoint.getId());
                _loresetPoint.setPointName(loresetPoint.getPointName().trim());
                _loresetPoint.setTeachingNamePage(loresetPoint.getTeachingNamePage());
                _loresetPoint.setDepict(loresetPoint.getDepict());
                _loresetPoint.setFrequency(loresetPoint.getFrequency());
                //暂时注掉，后续可能添加
//                _loresetPoint.setFraction(loresetPoint.getFraction().trim());
                _loresetPoint.setQuestionCount(loresetPoint.getQuestionCount());
                this.updateById(_loresetPoint, null);
            } else {//创建
                this.save(loresetPoint);
            }
        }
        return loresetPoint;
    }

    /**
     * 通过知识体系查询知识列表并分层
     *
     * @param loresetIds 知识体系ID串
     * @param loresetData 是否设置知识体系数据
     * @return 分层好的知识点列表
     */
    public List<SysLoresetPoint> findLayeredLoresetPoint(String loresetIds,boolean loresetData){
        List<SysLoresetPoint> loresetPointList = this.findLoresetPointListByLoresetIds(loresetIds);
        if(ObjectUtils.isNotEmpty(loresetPointList) && loresetData){
            String _loresetIds = loresetPointList.stream().map(e->e.getLoresetId().toString()).distinct().collect(Collectors.joining(","));
            List<SysLoreset> sysLoresetList = sysLoresetBiz.findLorestListByIds(_loresetIds,false,false,false);
            if(ObjectUtils.isNotEmpty(sysLoresetList)){
                Map<BigDecimal,SysLoreset> sysLoresetMap = sysLoresetList.stream().collect(Collectors.toMap(e->e.getId(),e->e));
                loresetPointList.forEach(point->{
                    SysLoreset sysLoreset = sysLoresetMap.get(point.getLoresetId());
                    point.setSysLoreset(sysLoreset);
                });
                loresetPointList = this.handleLayered(loresetPointList,true);
            }
        }
        return loresetPointList;
    }

    /**
     * 通过知识体系查询知识列表并分层
     *
     * @param loresetIds 知识体系ID串
     * @return 分层好的知识点列表
     */
    public Map<BigDecimal, List<SysLoresetPoint>> findLayeredLoresetPoint(String loresetIds) {
        List<SysLoresetPoint> loresetPointList = findLoresetPointListByLoresetIds(loresetIds);
        if (ObjectUtils.isNotEmpty(loresetPointList)) {
            //以知识体系ID分组
            Map<BigDecimal, List<SysLoresetPoint>> pointListMap = loresetPointList.stream().collect(Collectors.groupingBy(e -> e.getLoresetId()));
            pointListMap.forEach((key, value) -> {
                List<SysLoresetPoint> _list = this.handleLayered(value, true);
                pointListMap.put(key, _list);
            });
            return pointListMap;
        }
        return null;
    }

    /**
     * 通过知识体系ID串，查询知识点列表
     *
     * @param loresetIds 知识体系ID串
     * @return 知识体系列表
     */
    public List<SysLoresetPoint> findLoresetPointListByLoresetIds(String loresetIds) {
        if (StringUtils.isNotEmpty(loresetIds)) {
            loresetIds = StringUtils.subHeadTailString(loresetIds, ",");
            if (StringUtils.isNotEmpty(loresetIds)) {
                List<SysLoresetPoint> loresetPointList = this.find(" loresetId in (" + loresetIds + ")", null, null);
                return loresetPointList;
            }
        }
        return null;
    }

    /**
     * 处理分层
     *
     * @param loresetPointList
     * @return
     */
    private List<SysLoresetPoint> handleLayered(List<SysLoresetPoint> loresetPointList, boolean layered) {
        if (ObjectUtils.isNotEmpty(loresetPointList) && layered) {
            Map<BigDecimal, List<SysLoresetPoint>> loresetPointListMap = loresetPointList.stream().collect(Collectors.groupingBy(e -> e.getParentId()));
            //得到父级
            List<SysLoresetPoint> parentList = loresetPointListMap.get(new BigDecimal(0));
            if (ObjectUtils.isNotEmpty(parentList)) {
                parentList.forEach(e -> {
                    List<SysLoresetPoint> childList = loresetPointListMap.get(e.getId());
                    e.setChildLoresetPointList(childList);
                });
            }
            return parentList;
        }
        return loresetPointList;
    }


    /**
     * 通过ID获取知识点数据
     *
     * @param ids     知识点id
     * @param layered 分层，即二级知识点放入一级知识点
     * @return 考点
     */
    public Map<BigDecimal, SysLoresetPoint> findLoresetPointByIdsToMap(String ids,
                                                                       boolean layered) {
        ids = DataUtil.filterNotNumberStr(ids);
        if (StringUtils.isEmpty(ids)) {
            return Collections.emptyMap();
        }
        String where = " id in (" + ids + ")";
        List<SysLoresetPoint> sysLoresetPointList = this.find(where, 0, Collections.emptyList());
        this.handleLayered(sysLoresetPointList, layered);
        return sysLoresetPointList.stream().collect(Collectors.toMap(SysLoresetPoint::getId, Function.identity()));
    }

    /**
     * 刷新试卷试题量
     * @param countMap 更新数量
     * @param status 试题状态
     */
    public void refreshLoresetPoint(Map<String, Integer> countMap,int status) {
        if(ObjectUtils.isNotEmpty(countMap)){
            Map<String,Integer> _countMap = new HashMap<>();
            Set<String> idSet = new HashSet<>();
            countMap.forEach((k,v)->{
                String[] arr = k.split("#");
                IntStream.range(0,arr.length).forEach(index->{
                    String ids = arr[index];
                    ids = StringUtils.subHeadTailString(ids,",");
                    String[] idArr = ids.split(",");
                    IntStream.range(0,idArr.length).forEach(i->{
                        if(i>0){
                            String id = idArr[i];
                            idSet.add(id);
                            Integer count = _countMap.get(id);
                            if(count==null){
                                _countMap.put(id,v);
                            }else{
                                _countMap.put(id,count + v);
                            }
                        }
                    });
                });
            });
            Map<BigDecimal,SysLoresetPoint> pointMap = this.findLoresetPointByIdsToMap(idSet.stream().collect(Collectors.joining(",")),false );
            List<SysLoresetPoint> pointList = new ArrayList<>();
            if(ObjectUtils.isNotEmpty(pointMap)){
                pointMap.forEach((k,v)->{
                    SysLoresetPoint point = new SysLoresetPoint();
                    point.setId(k);//原有ID
                    point.setQuestionCount(v.getQuestionCount());//原试题量
                    Integer count = _countMap.get(String.valueOf(k));
                    if(count==null){
                        count = 0;
                    }
                    if(status==1){
                        point.setQuestionCount(point.getQuestionCount() + count);
                    }else{
                        point.setQuestionCount(point.getQuestionCount() - count);
                    }
                    if(point.getQuestionCount().intValue() < 0){
                        point.setQuestionCount(0L);
                    }
                    pointList.add(point);
                });
            }
            if(ObjectUtils.isNotEmpty(pointList)){
                this.updateBatch(pointList);
            }
        }
    }
}
